﻿#include "ssLogBase.h"
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#else
#include <sys/stat.h>
#endif
#include "../time/ssTime.h"


namespace StarSeeker
{

ssLogBase::ssLogBase()
	:m_subsection(0), m_printFlag(63), m_fileFlag(60)
{
	memset(m_lastDate, 0, sizeof(m_lastDate));
	m_info.GetInfo();
	m_folder = "./";
	m_folder += m_info.m_name.c_str();
	m_folder += "_logs";
}

ssLogBase::ssLogBase(u8 type, const char* path)
	:m_printFlag(63), m_fileFlag(60)
{
	memset(m_lastDate, 0, sizeof(m_lastDate));
	m_info.GetInfo();
	if (path)
	{
		m_folder = path;
	} 
	else
	{
		m_folder = "./";
		m_folder += m_info.m_name.c_str();
		m_folder += "_logs";
	}
	m_subsection = type == 1 ? 1 : 0;
}


ssLogBase::~ssLogBase()
{
	CloseFile();
}

void ssLogBase::OutPut2Buffer(SS_LOG_TYPE type, const char *pLogString, ssString& buffer)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	const char* pType = ssLogBase::GetLogType(type);
	buffer.Format("[%s]%s", tempTime, pType);
	buffer += pLogString;
}

void ssLogBase::OutPutEx2Buffer(SS_LOG_TYPE type, const char *pLogString, va_list &vaList, ssString& buffer)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	const char* pType = ssLogBase::GetLogType(type);
	buffer.Format("[%s]%s", tempTime, pType);
	char* currentBuffer = (char*)buffer.At(buffer.Length());

	// 处理变长参数
	int len = vsnprintf(currentBuffer, buffer.ResidueSize(), pLogString, vaList);
	if (len <= 0)
		buffer += "****vsnprintf error!****";
	else
		buffer.SetLength((u32)len, true);
}

void ssLogBase::OutPut2Msg(SS_LOG_TYPE type, const char *pLogString, ssMsg_s& msg)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	const char* pType = ssLogBase::GetLogType(type);

	u32 len = StrLen(pLogString);
	char* logStr = new char[len + 20];
	snprintf(logStr, len + 20, "[%s]%s%s", tempTime, pType, pLogString);

	msg.msgID = 1110111;
	msg.subID = type;
	msg.param[0] = (ulint)logStr;
}

void ssLogBase::OutPutEx2Msg(SS_LOG_TYPE type, const char *pLogString, va_list &vaList, ssMsg_s& msg)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	char tempBuf[LOG_PRINT_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	const char* pType = ssLogBase::GetLogType(type);
	// 处理变长参数
	int len = vsnprintf(tempBuf, LOG_PRINT_LEN - 1, pLogString, vaList);
	if (len <= 0)
	{
		memcpy(tempBuf, "****vsnprintf error!****", 25);
	}
	char* logStr = new char[LOG_STR_LEN];
	snprintf(logStr, LOG_STR_LEN - 1, "[%s]%s%s", tempTime, pType, tempBuf);

	msg.msgID = 1110111;
	msg.subID = type;
	msg.param[0] = (ulint)logStr;
}

void ssLogBase::SaveToFile(const char * pStr)
{
	//是否新建文件
	MakeDir();
	if (!m_fstream.is_open())
	{
		m_fstream.open(m_filePath.GetString(), std::ios::app);
	}
	if (m_fstream.is_open())
	{
		m_fstream << pStr << std::endl;
		CloseFile();
	}
}

void ssLogBase::MakeDir()
{
	bool change = false;
	char szTime[32] = { 0 };
	if (m_subsection==1)
	{
		ssTime::GetLocalTimeYMDH(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMDH(m_lastDate);
			change = true;
		}
	} 
	else
	{
		ssTime::GetLocalTimeYMD(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMD(m_lastDate);
			change = true;
		}
	}
	if (change)
	{
		//建立logs文件夹
#ifdef _WIN32
		::_mkdir(m_folder.GetString());
#else
		::mkdir(m_folder.GetString(), S_IRWXU);
#endif
		//建立日期文件
		m_filePath = m_folder;
		m_filePath += "/";
		m_filePath += m_lastDate;
		m_filePath += ".log";
	}
}

void ssLogBase::CloseFile()
{
	if (m_fstream.is_open())
	{
		m_fstream.clear();
		m_fstream.close();
	}
}

const char* ssLogBase::GetLogType(SS_LOG_TYPE type)
{
	switch (type)
	{
	case LOG_TRACE:
		return "[TRACE]";
	case LOG_DEBUG:
		return "[DEBUG]";
	case LOG_INFO:
		return "[INFO]";
	case LOG_WARN:
		return "[WARN]";
	case LOG_ERROR:
		return "[ERROR]";
	case LOG_FATAL:
		return "[FATAL]";
	case LOG_FILE_ONLY:
		return "[FILE]";
	default:
		return "[?]";
	}
}

}
